package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

public class Hero extends AbstractMapleStoryObject {
    public static Image[] imgs = new Image[100];

    static {
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_stand" + i);
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_stand" + (i - 4));
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_walk" + (i - 8));
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_walk" + (i - 13));
        }
        imgs[18] = ImageUtil.getImage("hero_right_prone");
        imgs[19] = ImageUtil.getImage("hero_left_prone");

        imgs[20] = ImageUtil.getImage("hero_right_jump");
        imgs[21] = ImageUtil.getImage("hero_left_jump");

        for (int i = 22; i < 26; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22));
        }
        for (int i = 26; i < 30; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26));

        }
    }

    /**
     * 中介者
     */
    public MapleStoryClient msc;

    public Hero() {
    }

    /**
     * 人物血量上限
     */
    public int HP;
    public int MAX_HP = 1000;
    /**
     * 人物魔法值上限
     */
    public int MP;
    public int MAX_MP = 1000;
    /**
     * 基础攻击力
     */
    public int ATT;
    /**
     * 伤害值
     */
    public int hitValue;

    public Random r = new Random();

    public Hero(MapleStoryClient msc, int x, int y) {
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.MP = MAX_MP;
        this.HP = MAX_HP;
        this.ATT = 1000;

        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;
    }

    /**
     * 一直加的计数器
     */
    public int count = 0;
    /**
     * 计算当前画第几张图
     */
    public int step = 0;

    /**
     * 左右的开关
     */
    public boolean left, right, down, jump, shoot, pickup;

    @Override
    public void draw(Graphics g) {
        switch (dir) {
            case RIGHT:
                switch (action) {
                    case STAND:
                        //right stand
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[step++ % 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //right walk
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 5) + 8], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 5 + 8], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18], x, y + 32, null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20], x, y, null);
                        break;
                    case SHOOT:
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 22], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 22], x, y, null);
                        }
                        break;
                }

                break;
            case LEFT:
                switch (action) {
                    case STAND:
                        //left stand
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //left walk
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 5) + 13], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 5 + 13], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[19], x, y + 32, null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[21], x, y, null);
                        break;
                    case SHOOT:
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 26], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 26], x, y, null);
                        }
                        break;
                    default:
                        break;
                }

                break;

            default:
                break;
        }
        if(HP < MAX_HP) {
            blooBar.draw(g);
        }
        move();
    }

    @Override
    public void move() {
        if (left) {
            x -= speed;
            this.action = Action.WALK;
        }
        if (right) {
            x += speed;
            this.action = Action.WALK;
        }
        if (jump) {
            jump(msc.grounds);

        } else {
            //自由落体（往下掉）
            jumpDown(msc.grounds);
        }
        if (shoot) {
            shoot();
        }
        if (pickup) {
            pickup(msc.items);
        }

        confirmStatus();
        outOfBound();
    }

    /**
     * 射击时常的变量
     */
    private int shootCount = 0;

    /**
     * 射击的方法
     */
    private void shoot() {
        shootCount++;

        if (shootCount % 10 == 0) {

            shoot = false;
            this.MP -= 5;
            Arrow arrow;

            if (dir == Direction.RIGHT) {
                arrow = new Arrow(msc, x + this.width, y + this.height / 2 + 8, dir);
            } else {
                arrow = new Arrow(msc, x, y + this.height / 2 + 8, dir);
            }
            msc.arrows.add(arrow);
        }
    }

    private double v0 = Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t = 0.7;

    /**
     * 跳跃的方法
     */
    private void jump(List<Ground> grounds) {

        if (!drop) {
            //向上跳（竖直上抛）
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;

            //什么时候往下掉
            if (vt <= 0) {
                vt = 0;
                drop = true;
            }
        } else {
            jumpDown(grounds);
        }

//        //自由落体的结束位置
//        if (y >= 500) {
//            jump = false;
//            v0 = Constant.INIT_JUMP_SPEED;
//            vt = 0.0;
//            y = 500;
    }

    private boolean drop = true;

    public void jumpDown(List<Ground> grounds) {
        //掉的过程
        vt = v0 + g * t;
        delta_height = v0 * t;
        v0 = vt;
        y += delta_height;
        //什么时侯停止自由落体
        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle()) && this.y <= ground.y - this.height + 40) {
                //停了
                if (this.y >= ground.y - this.height) {
                    this.y = ground.y - this.height;
                    drop = false;
                    jump = false;
                    v0 = Constant.INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                } else {
                    drop = true;
                }
            }
        }
    }

    /**
     * 根据当前人物的左右开关，确定人物方向
     */
    private void confirmStatus() {
        if (left && !right) {
            this.dir = Direction.LEFT;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (right && !left) {
            this.dir = Direction.RIGHT;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (down) {
            this.action = Action.PRONE;
        } else if (jump) {
            this.action = Action.JUMP;
        } else if (shoot) {
            this.action = Action.SHOOT;
        }
        //都按下或者都不按下
        else {
            this.action = Action.STAND;
        }
    }

    /**
     * 按键的方法
     *
     * @param e 键盘事件对象
     */
    public void keyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                left = true;
                x -= speed;
                break;

            case KeyEvent.VK_D:
                right = true;
                x += speed;
                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K://跳跃
                jump = true;
                break;
            case KeyEvent.VK_J://射击
                shoot = true;
                break;
            case KeyEvent.VK_L://拾取
                pickup = true;
                break;
            case KeyEvent.VK_I://显示道具包

                break;
            case KeyEvent.VK_W://
            default:
                break;
        }
    }

    /**
     * 释放键的方法
     *
     * @param e 键盘事件
     */

    public void keyReleased(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                left = false;
                break;
            case KeyEvent.VK_D:
                right = false;
                break;
            case KeyEvent.VK_S:
                down = false;
                break;
            case KeyEvent.VK_L://拾取
                pickup = false;
                break;
            default:
                break;
        }

    }

    /**
     * 人物出界
     */
    private void outOfBound() {
        if (this.x <= 0) {
            this.x = 0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width) {
            this.x = Constant.GAME_WIDTH - this.width;
        }
        if (this.x >= 1075 - this.width && this.y >= 690 - this.height + 40) {
            this.x = 1075 - this.width;
            this.y = 690 - this.height + 40;
        }
//        if (this.x >= 400 - this.width && this.y >= 650 - this.height + 40 && this.x <= 800 - this.width){
//            this.x = 400 - this.width;
//            this.y = 650 - this.height + 40;
////        }
//        if (this.dir == Direction.LEFT) {
//            if (this.x <= 800 && this.y >= 650 - this.height + 40 && this.x >= 400 - this.width) {
//                this.x = 800;
//            }
        //       }
        if (this.x >= 1075 - this.width && this.y >= 630 - this.height + 40) {
            this.x = 1075 - this.width;
            this.y = 630 - this.height + 40;
        }

        if (this.x >= 1150 - this.width && this.y >= 570 - this.height + 40) {
            this.x = 1150 - this.width;
            this.y = 570 - this.height + 40;
        }

    }

    /**
     * 拾取道具的方法
     *
     * @param item 被拾取的道具对象
     * @return 是否拾取
     */
    private boolean pickup(Item item) {
        if (item.live && this.getRectangle().intersects(item.getRectangle())) {
            item.live = false;
            //存放之前的道具包里面的每一个进行判断

            for (int i = 0; i < msc.itemPackage.items.size(); i++) {

                Item itm = msc.itemPackage.items.get(i);
                //如果相同，数量+1
                if (item.type == itm.type) {
                    itm.qty += 1;
                    return false;
                }
            }
            //业务 放入道具包
            msc.itemPackage.items.add(item);
            // msc.items.add(item);(错误的方法)
//            //业务
//            switch (item.type){
//                case 0:
//                    this.HP += 50;
//                    break;
//                case 1:
//                    this.HP += 100;
//                    break;
//                case 2:
//                    this.HP += 300;
//                    break;
//                case 3:
//                    this.MP += 100;
//                    break;
//                default:
//                    break;
//            }
//            if (HP >= MAX_HP){
//                HP = MAX_HP;
//            }
//            if (MP >= MAX_MP){
//                MP = MAX_MP;
//            }

        }
        return false;
    }

    /**
     * 拾取一堆道具
     *
     * @param items 道具容器
     * @return 是否拾取到
     */
    public boolean pickup(List<Item> items) {
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if (pickup(item)) {
                return true;
            }
        }
        return false;
    }

    public Hero.BlooBar blooBar = new Hero.BlooBar();

    class BlooBar extends AbstractMapleStoryObject {
        private Image img;

        public BlooBar() {
            this.img = ImageUtil.getImage("blood");
            this.width = img.getWidth(null);
        }

        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width/this.width * Hero.this.HP / Hero.this.MAX_HP;
            for (int i = 0; i < n; i++) {
                g.drawImage(img,Hero.this.x + (i * this.width),Hero.this.y - 10,null);
            }
        }


    }
    /**
     * 爬行的方法
     * @param grounds 碰撞位
     */
    public boolean climb;
    private void climb(List<Ground> grounds) {
        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle()) && climb) {
                y -= 8;
            }
        }
    }

}



